<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0">
    <title>ws test</title>
    <link rel="stylesheet" href="/reset.css">
    <script>
        var pageConfig = {};
        pageConfig.evalId = 1000;
    </script>
</head>
<body>
<div id="app" class="content" v-cloak>
    <p style="text-align: center" v-show="list.length < 1">-- 暂无数据 --</p>

    <span class="card" v-for="item in list">
       [ {{item.id}} - {{item.name}} ] ,
    </span>

    <hr>

    <div v-for="item in wsMessage">
        {{item}}
    </div>

</div>

<script src="/vue/vue.min.js"></script>
<script src="/axios/axios.min.js"></script>
<script>
    var app = new Vue({
        el: '#app',
        created: function () {
            this.loadList('default http');
            this.sockOpen();
        },
        data: {
            id: 1,
            list: [],
            webSocket: {},
            webSocketState: -1,
            webSocketInitLock: false,
            webSocketReopenTask: -1,
            webSocketHeartBeatTask: -1,
            webSocketNotifyReopenLock: false,
            refreshListTask: -1,
            wsMessage: [],
            wsRetryCount: 0,
            wsMaxRetryCount: 10
        },
        methods: {
            sockOpen() {
                if (typeof(WebSocket) != "function") {
                    this.refreshList();
                } else {
                    this.notifyInit();
                }
            },
            refreshList() {
                var self = this;

                self.consoleLog('启用http轮询...');

                var time =  6 * 1000;// 6 秒刷新一次
                self.refreshListTask = setInterval(function () {
                    self.loadList('http');
                }, time);
            },
            loadList(name) {
                var self = this;
                self.list.push({
                    id: self.id++,
                    name: name
                })
            },
            getHost() {
                return location.hostname+":"+location.port;
            },
            consoleLog(message) {
                this.wsMessage.push(message);
            },
            notifyInit() {
                var self = this;
                if (self.webSocketInitLock) return;
                self.webSocketInitLock = true;

                var host = this.getHost();
                this.webSocket = new WebSocket("ws://" + host + "/sequenceChangeNotifyWebSocket");
                window.clearInterval(self.webSocketHeartBeatTask);

                this.webSocket.onopen = function (evnt) {
                    self.webSocketState = 1;
                    self.consoleLog('[ws opened] : ' + JSON.stringify(evnt));
                    //发送消息
                    var message = {
                        'type': 'register',
                        'id': pageConfig.evalId
                    };
                    var msg = JSON.stringify(message);
                    self.consoleLog('[ws send msg] : ' + msg);
                    self.webSocket.send(msg);

                    var time =  3 * 1000 * 60;//3分钟发送一次ws心跳
                    self.webSocketHeartBeatTask = setInterval(function () {
                        var message = {
                            'type': 'ping',
                            'id': pageConfig.evalId
                        };
                        var msg = JSON.stringify(message);
                        self.consoleLog('[ws send msg] : ' + msg);
                        self.webSocket.send(msg);
                    }, time);
                };

                this.webSocket.onmessage = function (evnt) {
                    var messageText = evnt.data;
                    self.consoleLog('[ws get message] :' + messageText);
                    try {
                        var message = JSON.parse(messageText);
                        if (message.type === 'sequenceChanged') {
                            self.loadList('ws');
                        }
                    } catch (e) {
                        console.log(e);
                    }
                };

                this.webSocket.onerror = function (evnt) {
                    self.consoleLog('[ws error] : ' + JSON.stringify(evnt));
                    self.webSocketInitLock = false;
                    self.notifyReopen();
                };

                this.webSocket.onclose = function (evnt) {
                    self.consoleLog('[ws closed] : ' + JSON.stringify(evnt));
                    self.webSocketInitLock = false;
                    self.notifyReopen();
                };
            },
            notifyReopen() {
                var self = this;
                if (self.webSocketNotifyReopenLock) return;
                self.webSocketNotifyReopenLock = true;

                this.notifyClose();

                var time = 20 * 1000;//断线20秒一次重连
                self.webSocketReopenTask = setInterval(function () {
                    self.consoleLog(self.webSocketState);

                    if (self.wsRetryCount >= self.wsMaxRetryCount) {
                        self.consoleLog('已到最大重试次数 ：' + self.wsRetryCount);
                        self.webSocketNotifyReopenLock = false;
                        window.clearInterval(self.webSocketReopenTask);
                        self.refreshList();
                    } else if(self.webSocketState === -1) {
                        self.consoleLog('[ws reopen] websocket try reopen ['+(self.wsRetryCount++)+'] ...');
                        self.notifyInit();
                    } else {
                        self.consoleLog('[ws reopen success] websocket reopen success');
                        self.webSocketNotifyReopenLock = false;
                        window.clearInterval(self.webSocketReopenTask);
                    }
                }, time);
            },
            notifyClose() {
                this.webSocketInitLock = false;
                this.webSocketState = -1;
                window.clearInterval(self.webSocketHeartBeatTask);
            },
        }
    })
</script>
</body>
</html>